<?php
/**
 * @desc 支付宝.转账交易查询
 * @document https://docs.open.alipay.com/api_28/alipay.fund.trans.order.query/
 * @author Vincent
 */

namespace young\payment;

use young\Common;

class AliFundTransQuery extends AliConfig
{
    //交易状态
    private $tradeStatus = [
      'SUCCESS' => '成功',
      'FAIL'    => '失败',
      'INIT'    => '等待处理',
      'DEALING' => '处理中',
      'REFUND'  => '退票',
      'UNKNOWN' => '状态未知'
    ];

    public function run($data)
    {
        $this->setConfig($data['config']);
        return $this->handle($data['order_sn']);
    }

    /**
     * @param $orderSn 商户订单号
     * @return bool
     * @throws \Exception
     */
    private function handle($orderSn)
    {
        $common = [];
        $common['app_id'] = $this->appId;
        $common['method'] = 'alipay.fund.trans.order.query';
        $common['format'] = self::FORMAT;
        $common['charset'] = self::CHARSET;
        $common['sign_type'] = self::SIGN_TYPE;
        $common['timestamp'] = date('Y-m-d H:i:s', time());
        $common['version'] = self::VERSION;
        $common['biz_content'] = [];
        $common['biz_content']['out_biz_no'] = $orderSn;
        $common['biz_content'] = json_encode($common['biz_content'], JSON_UNESCAPED_UNICODE);
        $common = array_filter($common);

        ksort($common);

        $rsa2 = new AliRsa2;

        //签名
        $rsa2->setKey($rsa2->getRsaKeyValue($this->rsaPrivateKey, 'private'));
        $common['sign'] = $rsa2->encrypt(urldecode(http_build_query($common)));
        $common = $rsa2->splicingString($common);
        $result = Common::request_get(self::GETEWAY_URL . '?' . $common);

        $result = json_decode($result, true);
        $data = $result['alipay_fund_trans_order_query_response'];

        //验证签名
        $rsa2->setKey($rsa2->getRsaKeyValue($this->aliPublicKey, 'public'));
        $verifySign = $rsa2->rsaVerify(json_encode($data, JSON_UNESCAPED_UNICODE), $result['sign']);

        if ($verifySign === true) {
            if ($data['code'] == '10000') {
                $result = [
                  'error'    => false,
                  'get_code' => $data['out_biz_no'],
                  'order_id' => $data['order_id'],
                  'pay_date' => $data['pay_date'],
                  'status'   => $this->tradeStatus[$data['status']]
                ];
                return $result;
            } else {
                throw new \Exception($data['sub_msg']);
            }
        } else {
            throw new \Exception('签名失败');
        }
    }
}